Viewing Animated GIF Files with LBbrowse.DLL

© 2005, Janet Terra

author contact:

janetterra@yahoo.com

You've found the perfect animated gif and you'd like to display it in your Liberty BASIC GUI. This hasn't been possible with Liberty BASIC. There are some workarounds you could have used.

EXTRACT the Frames for Individual Display

Many drawing tools will allow you to extract the individual frames. You can then save each frame individually. Once the individual frames are loaded in your Liberty BASIC program, the frames can be cycled in rapid succession to simulate animation. This technique is used in [Animated Titles] in [Newsletter Issue 127]. A major problem with this technique is memory management to minimize graphic memory requirements and flickering. A second problem is that only gifs that are composed of complete frames can be reasonably extracted this way. The frames of most animated gifs only display those pixels that are to be changed for that frame. The other pixels are painted in the designated transparent color. This renders the extracted individual frames ineffective for single displays.

CONVERT to Sprites

Converting each frame to a sprite is certainly a viable option. That will eliminate the flickering and memory management is not a problem. Again, this option is only practical with gifs having complete frames. Extract the frames as described in the previous paragraph and save them as bitmaps. Those extracted bitmaps will then need to be masked. The easiest way to mask is found in your Liberty BASIC Help Manual Contents> Language Syntax and Usage> Sprites> Add a Mask.

DISPLAY as an AVI

Up until now, converting the GIF to an AVI has been the best option. If you've already extracted the individual bitmap frames from the gif, you can use the AVI Construction Tool in [Liberty BASIC Workshop] to create the AVI. You may be able to find a drawing tool that will convert an animated gif to an AVI. One such tool is [Movies13 by Jansoft]. Whatever method your method of choice, use Alyce's code presented in [API Corner - Animation Control], [Newsletter Issue #128] to display the AVI. Up until now, this has probably been the best option. The only preparatory modification required by the programmer is the conversion to AVI. There are no problems with flickering or memory management. Once again, though, the problem arises with only gifs made of complete frames being appropriate for this method.

ANIMATED GIFS as ANIMATED GIFS

The newly released [lbbrowse.dll] by Alyce Watson allows animated gifs to be imbedded into your Liberty BASIC programs as animated gifs. Not only are no frame extractions and conversions necessary, but flickering and memory management problems are nonexistant as well. You will need to make some adjustments when opening the browser window to hide the vertical and horizontal scroll bars. The results may be worth it as the graphic persists without further flushing commands.

Getting the GIF DIMENSIONS

Obtaining the dimensions of a bitmap is well documented by Alyce in [Getting the Dimensions of a Bitmap] in [Newsletter Issue #100]. In a similar fashion, the dimensions of a gif file can also be found in the header.

The width and height found in these bytes are the logical width and height. The actual width and height of each frame may differ. For most purposes, the logical width and height are sufficient in defining the display space required for the animated gif. For more information about identifying and deciphering gif file headers, visit [Wotsit's Format].

To find the GIF version, logical width and logical height of an animated GIF file, open the file as a sequential text file, use Line Input to store the contents in one string, then use the Mid$ function to extract the necessary information.

    Open gifFile$ for Input as #gif
        Line Input #gif, gifInfo$
    Close #gif
        gifSignature$ = Mid$(gifInfo$, 1, 3)
        gifVersion$ = Mid$(gifInfo$, 4, 3)
        gifWidth = Asc(Mid$(gifInfo$, 7, 1)) + Asc(Mid$(gifInfo$, 8, 1)) * 256
        gifHeight = Asc(Mid$(gifInfo$, 9, 1)) + Asc(Mid$(gifInfo$, 10, 1)) * 256

Defining the CHILD WINDOW

The lbbrowse.dll imbeds the browser in a child window. The child window is also required for displaying the animated gif. Once the dimensions of the gif are obtained, the dimensions of the child window can be defined. The window should be slightly larger than the gif itself to allow for the window borders. An addition of 8 pixels to the window width and height seems to work well.

    WindowWidth = gifWidth + 8
    WindowHeight = gifHeight + 8

Adjusting the BROWSER DIMENSIONS

The browser width and height need to be greater than the child window. This will hide the browser caption, vertical scrollbar and horizontal scrollbar. The height of a Windows XP caption is approximately 7 pixels higher than the classic Windows caption. If the animated gif is to display properly, this adjustment is necessary. To find the height of the caption on the user's system, make a call to GetSystemMetrics. As always, I am indebted to Alyce for providing the necessary call and code. This GetSystemMetrics function is also found in [FreeForm v4.020].

    captionHeight = GetSystemMetrics(_SM_CYCAPTION)

    Function GetSystemMetrics(nIndex)
        Calldll #user32, "GetSystemMetrics", _
            nIndex as Long,_
            GetSystemMetrics as Long
        End function

Adding 34 pixels to the width of the browser and 34 + captionHeight pixels to the height of the browser expands the caption and scrollbars beyond the child window display area.

    browserWidth = gifWidth + 34
    browserHeight = gifHeight + 34 + captionHeight 'Adjusts for Windows Classic and Windows XP

When the call to lbbrowse.dll "CreateBrowser" is made, the browser should be assigned negative x and negative y coordinates. This will hide the top and left edges of the browser, so the browser will appear borderless.

    Calldll #b, "CreateBrowser", _
        hChild as ulong, _
            -8 as long, _
            -8 as long, _
            browserWidth as long, _
            browserHeight as long,_
            url$ as ptr, _
            result as ulong

The Temporary HTML File

If the lbbrowser.dll is only being used to display an animated gif, no html file needs to be created. The url$ is passed as null.

    url$ = "" 'Do not actually load web page

If the animated gif is to be displayed against a background, a temporary html file is written to file. There are really only 5 elements required for this temporary html file.

< html >

< body bgColor="000000" > or < body background=bgPic.gif >

< img src="animPic.gif" >

< /body >

< /html >

The html tag designates the format. The background can be a solid color, as in bgColor = "000000" or a graphic, as in background=bgPic.gif. The img tag designates a graphic followed by the source of the graphic. Once these 5 lines are written to disk with the extension .html, the lbbrowse.dll can read the file and create a valid html page.

A SOLID Background

Html format requires RGB (red, green, blue) colors to be saved in hexadecimal format. The values of any of these three colors can range from 0 to 255. Each of the three colors takes up 2 bits and these 2 bits are concatenated together, in red-green-blue order, to form the rgb$. The RGB value of orange is 255 128 64. In Liberty BASIC, the color would be defined as

    Print #graph.bx, "Color 255 128 64"

To convert these numbers to hexadecimal, use the native Liberty BASIC command DecHex$(). To create an orange background, use

DecHex$(255) = "FF"

DecHex$(128) = "80"

DecHex$(64) = "40"

A GRAPHIC Background

Html files can load most standard picture formats: .bmp, .jpg, .gif, .wmp, and others. To load a picture as the background, insert the name of the desired background picture into the background command.

The dimension and coordinate adjustments are made with respect to the window size rather than the picture file. Therefore, it is not necessary to obtain the graphic size. As is the case with most files, if the picture file is not found in the current folder, the path to the picture file must be given.

< body background=bgPic.gif >

Html format will tile the picture when the dimensions of the browser are greater than the dimensions of the picture. Mike Bradbury's LBhtmlReports demo shows this tiling with libertyBackground.jpg.

Returning FOCUS to the Main Window

There remains just one missing piece. The imbedded browser resides in the child window, so this child window is the last window to receive focus. Although the animated gif should now be visible, the caption of the main window has faded, indicated lost focus. Mouse clicking the main window will return focus, but requiring your user to mouse click focus to the main window lacks professionalism. Instead, use the "SetFocus" call to return focus to the main window.

    CallDLL #user32, "SetFocus", _
        hMain as Long, _
        result as Long

The DEMOs

These demos will not function without lbbrowse.dll
******************************************************
LBBROWSE.DLL is copyright Alyce Watson, 2005.
LBBROWSE.DLL is freeware. You may use it in any application,
including commercial products. A credit to the author and a
link to the website must be included in your program's
documentation or readme file, and in any source code released
to the public.
Alyce Watson
http://alycesrestaurant.com/
******************************************************

In these printed demos, the "<" and the ">" have been replaced with Chr$(60) and Chr$(62). The zipped files include the "<" and the ">".

DEMO 1: Displaying just the animated GIF without loading a webpage

'DEMO OF LBBROWSDLL.DLL used as a GIF Viewer
'This demo will not function without lbbrowse.dll
'******************************************************
'LBBROWSE.DLL is copyright Alyce Watson, 2005.
'LBBROWSE.DLL is freeware. You may use it in any application,
'including commercial products. A credit to the author and a
'link to the website must be included in your program's
'documentation or readme file, and in any source code released
'to the public.
'Alyce Watson
'http://alycesrestaurant.com/
'******************************************************
'Demo written by Janet Terra for
'Liberty BASIC Newsletter Issue 137
'******************************************************
    Nomainwin
    ULX = 507
    ULY = 394
    WindowWidth = ULX
    WindowHeight = ULY

    UpperLeftX = Int((DisplayWidth - ULX)/2)
    UpperLeftY = Int((DisplayHeight - ULY)/2)

    Graphicbox #main.g, 0, 0, 500, 350
    Stylebits #main.g, 0, _WS_BORDER, 0, 0
    Menu #main, "&Files", "E&xit", [endDemo]
    Open "GIF Viewer" for Window_NF as #main
    #main, "Trapclose [endDemo]"
    #main.g, "Down; Fill Buttonface; Flush"
    hMain = hWnd(#main)
    captionHeight = GetSystemMetrics(_SM_CYCAPTION)

    Filedialog "Open Animated GIF","*.gif;",gifFile$
    If Lower$(Right$(gifFile$, 4)) = ".gif" Then
        Open gifFile$ for Input as #gif
            gifInfo$ = Input$(#gif, 29)
        Close #gif
        gifWidth = Asc(Mid$(gifInfo$, 7, 1)) + Asc(Mid$(gifInfo$, 8, 1)) * 256
        gifHeight = Asc(Mid$(gifInfo$, 9, 1)) + Asc(Mid$(gifInfo$, 10, 1)) * 256
    Else
        Notice "Invalid file format"
        Close #main
        End
    End If

    WindowWidth = gifWidth + 8
    browserWidth = gifWidth + 34
    WindowHeight = gifHeight + 8
    browserHeight = gifHeight + 34 + captionHeight 'Adjusts for Windows Classic and Windows XP

    UpperLeftX = Int((ULX - WindowWidth)/2)
    UpperLeftY = Int((ULY- WindowHeight)/2)

    Open "LB-Browser DLL Demo" for window_popup as #child
    #child "Trapclose [endDemo]"
    hChild = hwnd(#child)

    CallDLL #user32, "SetParent", _
    hChild As Long, _
        hMain As Long ,_
        result As Long

    Open "lbbrowse.dll" for dll as #b

    url$ = "" 'Do not actually load web page
    Calldll #b, "CreateBrowser", _
        hChild as ulong, _
            -8 as long, _
            -8 as long, _
            browserWidth as long, _
            browserHeight as long,_
            url$ as ptr, _
            result as ulong

    If result<>0 then
        Notice "Unable to load browser control."
        Goto [endDemo]
    End if

    Calldll #b, "Navigate", _
        gifFile$ as ptr, _
        ret as void

    CallDLL #user32, "SetFocus", _
        hMain as Long, _
        result as Long

    Wait

[endDemo]
    Calldll #b, "DestroyBrowser",  _
    re as void
    Close #b
    Close #child
    Close #main
    End

' This function blatantly lifted from FreeForm v4.020
' with permission of Alyce Watson
    Function GetSystemMetrics(nIndex)
        Calldll #user32, "GetSystemMetrics", _
            nIndex as Long,_
            GetSystemMetrics as Long
        End function

DEMO 2: Displaying an Animated GIF Against a Solid Background


'DEMO OF LBBROWSDLL.DLL used as a GIF Viewer
'This demo will not function without lbbrowse.dll
'******************************************************
'LBBROWSE.DLL is copyright Alyce Watson, 2005.
'LBBROWSE.DLL is freeware. You may use it in any application,
'including commercial products. A credit to the author and a
'link to the website must be included in your program's
'documentation or readme file, and in any source code released
'to the public.
'Alyce Watson
'http://alycesrestaurant.com/
'******************************************************
'Demo written by Janet Terra for
'Liberty BASIC Newsletter Issue 137
'******************************************************
    Nomainwin
    ULX = 800
    ULY = 600
    WindowWidth = ULX
    WindowHeight = ULY

    UpperLeftX = Int((DisplayWidth - ULX)/2)
    UpperLeftY = Int((DisplayHeight - ULY)/2)

    Graphicbox #main.g, 0, 0, ULX - 7, ULY - 28
    Stylebits #main.g, 0, _WS_BORDER, 0, 0
    Menu #main, "&Files", "E&xit", [endDemo]
    Open "GIF Viewer" for Window_NF as #main
    #main, "Trapclose [endDemo]"
    captionHeight = GetSystemMetrics(_SM_CYCAPTION)

    Colordialog,  "Black", hue$
    #main.g, "Down; Fill ";hue$;"; Flush"
    BGColor$ = Dec2Hex$(hue$)

    hMain = hWnd(#main)
    tempHTMLPath$ = DefaultDir$;"\tempHtml.html"

    Filedialog, "Load Animated GIF", "*.gif", gifFile$
    If Right$(gifFile$, 4) = ".gif" Then
        Open gifFile$ for Input as #gif
            gifInfo$ = Input$(#gif, 29)
        Close #gif
        gifWidth = Asc(Mid$(gifInfo$, 7, 1)) + Asc(Mid$(gifInfo$, 8, 1)) * 256
        gifHeight = Asc(Mid$(gifInfo$, 9, 1)) + Asc(Mid$(gifInfo$, 10, 1)) * 256
    Else
        Notice "Invalid file format"
        Close #main
        End
    End If

    null = tempHTML(tempHTMLPath$, BGColor$, gifFile$)

    WindowWidth = gifWidth + 8
    browserWidth = gifWidth + 34
    WindowHeight = gifHeight + 8
    browserHeight = gifHeight + 34 + captionHeight

    UpperLeftX = Int((ULX - WindowWidth)/2)
    UpperLeftY = Int((ULY- WindowHeight)/2)

    Open "LB-Browser DLL Demo" for window_popup as #child
    #child "Trapclose [endDemo]"
    hChild = hwnd(#child)

    CallDLL #user32, "SetParent", _
    hChild As Long, _
        hMain As Long ,_
        result As Long

    Open "lbbrowse.dll" for dll as #b

    Calldll #b, "CreateBrowser", _
        hChild as ulong, _
            -8 as long, _
            -8 as long, _
            browserWidth as long, _
            browserHeight as long,_
            tempHTMLPath$ as ptr, _
            result as ulong

    If result<>0 then
        Notice "Unable to load browser control."
        Goto [endDemo]
    End if

    CallDLL #user32, "SetFocus", _
        hMain as Long, _
        result as Long

    Wait

[endDemo]
    Calldll #b, "DestroyBrowser",  _
        re as void
        Close #b
    Close #child
    Close #main
    End

    Function Dec2Hex$(hue$)
        redHue = Val(Word$(hue$, 1))
        rH$ = DecHex$(redHue)
        If Len(rH$) <> 2 Then
            rH$ = "0";rH$
        End If
        greenHue = val(Word$(hue$, 2))
        gH$ = DecHex$(greenHue)
        If Len(gH$) <> 2 Then
            gH$ = "0";gH$
        End If
        blueHue = Val(Word$(hue$, 3))
        bH$ = DecHex$(blueHue)
        If Len(bH$) <> 2 Then
            bH$ = "0";bH$
        End If
        Dec2Hex$ = rH$;gH$;bH$
    End Function

    Function tempHTML(file$, BGColor$, picPath$)
        c1$ = Chr$(60);"html";Chr$(62)
        c2$ = Chr$(60);"body bgcolor = ";Chr$(34);BGColor$;Chr$(34);Chr$(62)
        c3$ = Chr$(60);"/body";Chr$(62)
        c4$ = Chr$(60);"/html";Chr$(62)
        c5$ = Chr$(60);"img src = ";Chr$(34);picPath$;Chr$(34);Chr$(62)
        Open file$ for Output as #h
            #h, c1$
            #h, c2$
            #h, c3$
            #h, c4$
            #h, c5$
        Close #h
    End Function

' This function blatantly lifted from FreeForm v4.020
' with permission of Alyce Watson
    Function GetSystemMetrics(nIndex)
        Calldll #user32, "GetSystemMetrics", _
            nIndex as Long,_
            GetSystemMetrics as Long
        End function

DEMO 3: Displaying an Animated GIF Against a Graphic Background


'DEMO OF LBBROWSDLL.DLL used as a GIF Viewer
'This demo will not function without lbbrowse.dll
'******************************************************
'LBBROWSE.DLL is copyright Alyce Watson, 2005.
'LBBROWSE.DLL is freeware. You may use it in any application,
'including commercial products. A credit to the author and a
'link to the website must be included in your program's
'documentation or readme file, and in any source code released
'to the public.
'Alyce Watson
'http://alycesrestaurant.com/
'******************************************************
'Demo written by Janet Terra for
'Liberty BASIC Newsletter Issue 137
'******************************************************
    Nomainwin
    ULX = 800
    ULY = 600
    WindowWidth = ULX
    WindowHeight = ULY

    UpperLeftX = Int((DisplayWidth - ULX)/2)
    UpperLeftY = Int((DisplayHeight - ULY)/2)

    Graphicbox #main.g, 0, 0, ULX - 7, ULY - 28
    Stylebits #main.g, 0, _WS_BORDER, 0, 0
    Menu #main, "&Files", "E&xit", [endDemo]
    Open "GIF Viewer" for Window_NF as #main
    #main, "Trapclose [endDemo]"

    Filedialog,  "Load Background Picture", "*.*", BG$

    hMain = hWnd(#main)
    tempHTMLPath$ = DefaultDir$;"\tempHtml.html"

    Filedialog, "Load Animated GIF", "*.gif", gifFile$

    null = tempHTML(tempHTMLPath$, BG$, gifFile$)

    WindowWidth = ULX  - 10
    browserWidth = ULX + 10
    WindowHeight = ULY - 10
    browserHeight = ULY + 10

    UpperLeftX = Int((ULX - WindowWidth)/2 - 4)
    UpperLeftY = Int((ULY- WindowHeight)/2 - 4)

    Open "LB-Browser DLL Demo" for window_popup as #child
    #child "Trapclose [endDemo]"
    hChild = hwnd(#child)

    CallDLL #user32, "SetParent", _
    hChild As Long, _
        hMain As Long ,_
        result As Long

    Open "lbbrowse.dll" for dll as #b

    Calldll #b, "CreateBrowser", _
        hChild as ulong, _
            -2 as long, _
            -2 as long, _
            browserWidth as long, _
            browserHeight as long,_
            tempHTMLPath$ as ptr, _
            result as ulong

    If result<>0 then
        Notice "Unable to load browser control."
        Goto [endDemo]
    End if

    CallDLL #user32, "SetFocus", _
        hMain as Long, _
        result as Long

    Wait

[endDemo]
    Calldll #b, "DestroyBrowser",  _
        re as void
        Close #b
    Close #child
    Close #main
    End

    Function tempHTML(file$, BG$, picPath$)
        c1$ = Chr$(60);"html";Chr$(62)
        c2$ = Chr$(60);"body background=";Chr$(34);BG$;chr$(34);Chr$(62)
        c3$ = Chr$(60);"/body";Chr$(62)
        c4$ = Chr$(60);"/html";Chr$(62)
        c5$ = Chr$(60);"img src = ";Chr$(34);picPath$;Chr$(34);Chr$(62)
        Open file$ for Output as #h
            #h, c1$
            #h, c2$
            #h, c3$
            #h, c4$
            #h, c5$
        Close #h
    End Function


DEMOS

The files GIFViewerDemo1.bas, GIFViewerDemo2.bas, and GIFViewerDemo3.bas are included in the zipped archive of this newsletter.


Home

Wire 1.0

Gif Viewer

Report Generation

Flow Charting

Stylebits Corner

Tip Corner

API Corner

CodeAChrome

Sprite Byte

Control Panel Applets

HTTPS Data

Eddie

Submissions

Index